/****************************************************************************
 *   Copyright (C) 2008 by 7552                                             *
 *   fiubataller2-08c1@gruposyahoo.com.ar                                   *
 *                                                                          *
 *  Licensed under the Apache License, Version 2.0 (the "License");         *
 *  you may not use this file except in compliance with the License.        *
 *  You may obtain a copy of the License at                                 *
 *                                                                          *
 *      http://www.apache.org/licenses/LICENSE-2.0                          *
 *                                                                          *
 *  Unless required by applicable law or agreed to in writing, software     *
 *  distributed under the License is distributed on an "AS IS" BASIS,       *
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.*
 *  See the License for the specific language governing permissions and     *
 *  limitations under the License.                                          *
 *                                                                          *
 ***************************************************************************/

#ifndef _LOGCACHE_
#define _LOGCACHE_

#define CACHE_SIZE 1048576
#include <map>
#include <fstream>
#include <string>
#include "LogRecords.h"

using namespace std;

namespace Taller2
{
namespace TransRec
{

const string _DEFAULT_DB_ = "oodb";

class LogCache
{
public:
	/**
		\brief Constructor de la clase.
	*/
    LogCache(const string &database);

	/**
		\brief Destructor de la clase.
	*/
    ~LogCache();

    /**
		\brief Actualiza el log no volatil a partir del contenido de la cache.
		Escribe sobre el log no volatil el contenido de la cache de log.
		El flush siempre es completo: toda la cache de log pasa al log no volatil cada vez que se hace.
     */
    int Flush();

	/**
		\brief �ste m�todo elimina del log no volatil los registro de transacciones terminadas y checkpoints viejos.
		Este m�todo no debe ser llamado unicamente durante la inicializaci�n del motor de transacciones.
	*/
	int CleanUpLog();

	/**
		\brief Devuelve el tama�o en bytes del log no volatil.
		\return Tama�o en bytes del log no volatil
	*/
	size_t GetFileSize();

    /**
		\brief Escribe una nueva entrada en log.
		Escribe una entrada en la cache de log. Puede disparar un flush del mismo
		\param reg Registro a escribir en el log. �ste puntero debe ser desalocado por el codigo cliente.
     */
    int WriteEntry(CLogRecord* reg);

	/**
		\brief Inicializa el registro de Checkpoint con los LSN de las transacciones abiertas.
		\param reg Registro a inicializar.
	*/
	void GetOpenTransactionsInfo(CCheckPointRecord* reg);

	/**
		\brief Devuelve el ultimo registro de Rollback asociado a \b transactionID
		\param transactionID ID de la transacci�n.
		\return Instancia al registro de Rollback. Debe ser desalocado por el codigo cliente.
	*/
	int FindRollback(int transactionID, CBasicOperationRecord* &rec);

	/**
		\brief Devuelve el ultimo registro de Commit asociado a \b transactionID
		\param transactionID ID de la transacci�n.
		\return Instancia al registro de Commit. Debe ser desalocado por el codigo cliente.
	*/
	CCommitRecord*   FindCommit(int transactionID);

	/**
		\brief Devuelve el registro anterior a rec perteneciente a la misma transacci�n.
		\param rec Instancia del registro actual. �ste es desalocado y remplazado por el registro anterior.
		\return devuelve \b true si se encontr� un registro anterior. Sino, devuelve \b false y rec no se desalocado.
	*/
	bool GetPrevRecordOfSameTransaction(CBasicOperationRecord* &rec);

	/**
		Devuelve el tipo de registro del ultimo registro y la posici�n de �ste.
	*/
	streampos GetLastEntryType(LogEntryType &entry);

	/**
		Devuelve el tipo  del registro siguiente al que comienza en \b pos, y la posici�n de �ste.
	*/
	streampos GetPrevEntryType(streampos pos, LogEntryType &entry);

	/**
		Devuelve el tipo  del registro siguiente al que comienza en \b pos, y la posici�n de �ste.
	*/

	streampos GetNextEntryType(streampos pos, LogEntryType &entry);

	/**
		Devuelve el ID de transacci�n  del registro que comienza en \b pos.
	*/

	int LoadReg(streampos pos,CLogRecord &rec, bool estados);

	void GetTransactionID(streampos pos, int& transactionID);

private:

    /**
		Cursor de escritura al array data
     */
	TLogRecordVector m_RecordBuffer;

	/**
		Tama�o en bytes de m_RecordBuffer.
	*/
	int m_CurrentSize;

    /**
		Contiene el ultimo lsn registrado en todo el log
     */
    int lastLsn;

    /**
		Handle del archivo de log no volatil
     */
    fstream file;

	/**
		Nombre del log no volatil
	*/
	string fileName;

    /**
		Contiene el ultimo lsn registrado para cada transaccion activa
     */
    map<int, int> lsnPerTransaction;


    void UpdateLsnPerTransaction(int & size);

    /**
		Escribe sobre el log no volatil el contenido de la cache de log. El flush siempre es
		completo: toda la cache de log pasa al log no volatil cada vez que se hace.
     */
    int FlushIfNecessary();

    /**
		Limpia el buffer (todo byte a 0xFF) y restaura el cursor de escritura al principio.
     */
    void Clear();

	///**
	//	Realiza la escritura del bloque de memoria \b data, de tama�o \b size,  al log no volatil.
	//*/
	//void AppendToFile(char* data, unsigned int size);


};

};
};

#endif
